﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using GlobalHelper;

namespace Standardization
{
    public class CompanyFive : IStandardIzation
    {
        /// <summary>
        /// 正规化时刻表
        /// </summary>
        /// <param name="origianlTimeTable"></param>
        /// <returns></returns>
        public DataTable StandardTimeTable(DataTable origianlTimeTable)
        {
            DataTable result = new DataTable();

            int rowAmount = origianlTimeTable.Rows.Count;
            int colAmount = origianlTimeTable.Columns.Count;

            IList<IList<string>> tableInfo = new List<IList<string>>();

            DataTable operatorTable = SetTokenName(origianlTimeTable);

            for (int i = 0; i < operatorTable.Rows.Count; i++)
            {
                IList<string> line = Helper.GetLine(operatorTable.Rows[i]);

                if (!IsEmptyLine(line))
                {
                    line = StandardLine(line);
                    tableInfo.Add(line);
                }
            }

            result = Helper.CreateDataTable(tableInfo, rowAmount, colAmount);

            return result;
        }





        /// <summary>
        /// 正规化数据行
        /// </summary>
        /// <param name="originalInfo"></param>
        /// <returns></returns>
        public static IList<string> StandardLine(IList<string> originalInfo)
        {
            if (IsEmptyLine(originalInfo))
            {
                return null;
            }

            IList<string> result = originalInfo;

            //1. 路牌名补标识(必须在补路牌名前)
            //result = CompleteTokenFlag(result);

            //2. 补路牌名(必须在补路牌标识后)
            //result = FillTokenName(result);

            //3. 清除发车时间后的标识(必须在4前)
            result = RemoveFlagWithNotEndDeparture(result);

            //4. 规范化路牌结束(必须在3后)
            result = FixTokenEnd(result);

            //5. 发车时间取整
            result = FixDeparture(result);

            //6. 合并下半班路牌与发车时间
            result = LocalHelper.CombinNightTokenName(result);

            return result;
        }

        

        /// <summary>
        ///清除发车时间后的标识
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static IList<string> RemoveFlagWithNotEndDeparture(IList<string> list)
        {
            IList<string> result = list;

            for (int i = 0; i < list.Count; i++)
            {
                string content = result[i].ToString();

                //2. 判断 含非数字
                if (Helper.CheckIsNumber(content))
                {
                    continue;
                }

                //3. 跳过,所有 路牌名,及 结束
                if (LocalHelper.IsTokenName(content))
                {
                    continue;
                }
                //3.1 跳过, 所有 路牌名 起始的
                if (LocalHelper.IsBeginWithTokenName(content))
                {
                    continue;
                }

                if (LocalHelper.IsStandEnd(content))
                {
                    continue;
                }

                //4. 去除非数字符号
                result[i] = Helper.RemoveContentFlag(content);
            }

            return result;
        }

        /// <summary>
        /// 发车时间取整
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static IList<string> FixDeparture(IList<string> list)
        {
            IList<string> result = list;

            for (int i = 0; i < list.Count; i++)
            {
                if (Helper.CheckIsDecimal(list[i]))
                {
                    Double d = Convert.ToDouble(list[i]);
                    list[i] = ToBig(d);
                }
            }

            return result;
        }


        private static string ToBig(Double d)
        {
            string result = string.Empty;

            d += 0.5;
            result = Convert.ToInt32(d).ToString();

            return result;
        }

        /// <summary>
        ///  修正路牌结束标志
        ///  包括上半班与下半班
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static IList<string> FixTokenEnd(IList<string> list)
        {
            IList<string> result = list;

            try
            {
                //1. 遍历, 读到结束
                for (int i = 0; i < result.Count; i++)
                {
                    if (LocalHelper.IsEndCompanyFive(result[i]))
                    {
                        //2. 判断 结束前是否是时间
                        if (i > 1 && Helper.CheckIsNumber(result[i - 1]))
                        {
                            //3. 如是则,在时间后加标准结束符
                            result[i - 1] += Helper.StandTokenEndFlag;

                            //4. 删除原结束格内容
                            result[i] = string.Empty;

                        }
                    }
                }

            }
            catch (Exception ex)
            {

                throw;
            }

            return result;
        }



        /// <summary>
        /// 判断是否为空行
        /// 1. 只有路牌起始,后面没有数据
        /// 2. 正行都是空的
        /// </summary>
        /// <param name="originalInfo"></param>
        /// <returns></returns>
        private static bool IsEmptyLine(IList<string> originalInfo)
        {
            if (originalInfo.Count <= 0)
            {
                return true;
            }

            bool result = true;

            for (int i = 1; i < originalInfo.Count; i++)
            {
                if (!string.IsNullOrEmpty(originalInfo[i]))
                {
                    result = false;
                    break;
                }
            }

            return result;
        }



        /// <summary>
        /// 对明细中所有的路牌名,加<>标记
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DataTable SetTokenName(DataTable dt)
        {
            if (Helper.IsEmpty(dt))
            {
                return dt;
            }

            DataTable result = dt;

            //1. 将首列中的所有非空项,收集为路牌名集合
            IList<string> tokenNames = GetTokenNames(result);

            //2. 根据路牌名集合,在明细中寻找所有匹配处
            for (int i = 0; i < result.Rows.Count; i++)
            {
                for (int j = 0; j < result.Columns.Count; j++)
                {
                    foreach (string tokenName in tokenNames)
                    {
                        if (IsSameToken(result.Rows[i][j].ToString(), tokenName))
                        {
                            //3. 修改匹配处, 加<>
                            result.Rows[i][j] = string.Format("<{0}>", result.Rows[i][j]);
                        }
                    }

                }
            }

            return result;
        }

        private static bool IsSameToken(string detail, string tokenName)
        {
            bool result = false;

            //1. 如果是 '< '开始的, '> ' 结束的, detail, 去除<>后与tokenName比较
            if (detail.StartsWith(Helper.TokenBeginFlag)
                && detail.EndsWith(Helper.TokenEndFlag))
            {
                string temp = detail;
                temp = temp.Replace(Helper.TokenBeginFlag, "");
                temp = temp.Replace(Helper.TokenEndFlag, "");

                //result = temp == tokenName;
            }
            //2. 否则,直接比较名称
            else
            {
                string detailTrim = Regex.Replace(detail, @"\s", "");
                string tokenNameTrim = Regex.Replace(tokenName, @"\s", "");

                result = detailTrim == tokenNameTrim;
            }


            return result;
        }

        /// <summary>
        /// 获得明细中所有路牌名称
        /// 依据首列
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        private static IList<string> GetTokenNames(DataTable dt)
        {
            IList<string> result = new List<string>();

            foreach (DataRow dataRow in dt.Rows)
            {
                if (!string.IsNullOrEmpty(dataRow.ItemArray[0].ToString()))
                {
                    result.Add(dataRow.ItemArray[0].ToString());
                }
            }

            return result;
        }

        #region NotUse

        /// <summary>
        /// 补路牌标识
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static IList<string> CompleteTokenFlag(IList<string> list)
        {
            IList<string> result = list;

            string tokenName = list[0].Trim();

            if (!string.IsNullOrEmpty(tokenName))
            {


                if (!tokenName.StartsWith(Helper.TokenBeginFlag))
                {
                    tokenName = Helper.TokenBeginFlag + tokenName;
                }

                if (!tokenName.EndsWith(Helper.TokenEndFlag))
                {
                    tokenName += Helper.TokenEndFlag;
                }

                result = list;

                result[0] = tokenName;

            }

            return result;
        }

        /// <summary>
        /// 补路牌名
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        private static IList<string> FillTokenName(IList<string> line)
        {
            IList<string> result = line;

            //1.1 取首列为路牌名
            string tokenName = result[0].ToString();

            int position = 0;

            if (!string.IsNullOrEmpty(tokenName))
            {


                //1.2 寻找第一个结束
                int firstEnd = 0;
                for (int i = 1; i < result.Count; i++)
                {
                    if (LocalHelper.IsEndCompanyFive(result[i]))
                    {
                        firstEnd = i;
                        break;
                    }
                }

                //1.3 寻找结束后的路牌
                int firstNodeAfterFirstEnd = firstEnd + 1;
                for (int i = firstNodeAfterFirstEnd; i < result.Count; i++)
                {
                    if (!string.IsNullOrEmpty(result[i]))
                    {

                        position = i;
                        break;
                    }
                }
            }
            else
            {
                //2.1 寻找第一个非空元作为路牌处理
                for (int i = 0; i < result.Count; i++)
                {
                    if (!string.IsNullOrEmpty(result[i]))
                    {

                        position = i;
                        break;
                    }
                }
            }


            #region opertaor

            //1.4 路牌加标识
            if (!result[position].StartsWith(Helper.TokenBeginFlag))
            {
                result[position] = Helper.TokenBeginFlag + result[position];
            }

            if (!result[position].EndsWith(Helper.TokenEndFlag))
            {
                result[position] += Helper.TokenEndFlag;
            }

            //1.5 将路牌名合并入首个发车时间
            if (position == result.Count)
            {
                throw new Exception("路牌名位于行末!");
            }
            if (Helper.CheckIsNumber(result[position + 1]))
            {
                result[position + 1] = result[position] + result[position + 1];
            }

            //1.6 清除原路牌名单元
            result[position] = string.Empty;

            #endregion

            return result;
        }

        #endregion
    }
}
